package com.xbibo.autoconfigure.dal.redis.support;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.util.CollectionUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

import static java.util.stream.Collectors.toMap;

/**
 * 类/接口注释
 *
 * @author jiangnan.zjn@alibaba-inc.com
 * @createDate 2017/9/23
 */
public class RedisEntityInfo<T, ID> {

    private final PropertyDescriptor[] descriptors;
    private BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance();

    private RedisProperty idProperty;

    /**
     * 版本
     */
    private int version;

    public RedisEntityInfo(Class<T> cls){
        descriptors = beanUtilsBean.getPropertyUtils().getPropertyDescriptors(cls);
    }
    /**
     * 类属性
     */
    private List<RedisProperty> properties;


    /**
     * 获取id数据
     * @param t 实体
     * @return ID
     */
    public ID getId(T t){
        if(idProperty == null || descriptors == null){
            return null;
        }
        String idName = idProperty.getName();
        Optional<PropertyDescriptor> descriptorOpti = Arrays.stream(descriptors)
                .filter(it -> idName.equals(it.getName()))
            .findFirst();
        if(!descriptorOpti.isPresent()){
            return null;
        }
        Method method = beanUtilsBean.getPropertyUtils().getReadMethod(descriptorOpti.get());
        Object o = null;
        try {
             o = method.invoke(t);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return (o == null) ? null : (ID)o;
    }


    public void setIdProperty(RedisProperty idProperty) {
        this.idProperty = idProperty;
    }

    public void setProperties(List<RedisProperty> properties) {
        this.properties = properties;
    }


    public Map<String, RedisProperty> getAliasMap(){
        if(CollectionUtils.isEmpty(properties)){
            return Collections.emptyMap();
        }
        return properties.stream().collect(toMap(RedisProperty::getAlias, x->x, (x1,x2)->x1));
    }

    public Map<String, RedisProperty> getNameMap(){
        if(CollectionUtils.isEmpty(properties)){
            return Collections.emptyMap();
        }
        return properties.stream().collect(toMap(RedisProperty::getName, x->x, (x1,x2)->x1));
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }
}
